package chen.web.config;

import java.util.HashSet;
import java.util.Set;

import chen.web.firewall.AbstractTable;
import chen.web.firewall.AbstractTable.Type;

public abstract class AbstractTableConfig<T extends AbstractTable<P, ?>, P> extends Config {

	protected Set<String> denyRules;
	protected Set<String> allowRules;
	protected static final String propertyName = "rules";
	
	public Set<String> getDenyRules(){
		return denyRules;
	}
	public Set<String> getAllowRules(){
		return allowRules;
	}
	
	public AbstractTableConfig(T table){
		denyRules = rules(table, Type.Deny);
		allowRules = rules(table, Type.Allow);
	}
	
	protected AbstractTableConfig(){}
	
	@Override
	protected void persist() {
		// TODO Auto-generated method stub
		StringBuilder sb = new StringBuilder();
		sb.append(Type.Deny.name())
			.append(":")
			.append(denyRules.toString())
			.append(Type.Allow.name())
			.append(":")
			.append(allowRules.toString());
		this.setProperty(propertyName, sb.toString());
	}

	protected Set<String> rules(T t, Type type){
		Set<P> list = t.rules(type);
		Set<String> rules = new HashSet<String>();
		for(P p : list){
			rules.add(stringValue(p));
		}
		return rules;
	}
	
	
	protected abstract String stringValue(P p);
	
	@Override
	protected void load(){
		denyRules = new HashSet<String>();
		allowRules = new HashSet<String>();
		String value = this.getProperty(propertyName);
		if(value == null || value.trim().length() == 0){
			return;
		}
		addRules(value, Type.Allow);
		addRules(value, Type.Deny);
	}

	private void addRules(String value, Type type){
		int idx = value.indexOf(type.name() + ":");
		if(idx != -1){
			int beginIndex = value.indexOf('[', idx);
			int endIndex = value.indexOf(']', beginIndex);
			String[] strRules = value.substring(beginIndex+1, endIndex).split(", ");
			addAll(type==Type.Allow?allowRules:denyRules, strRules);
		}
	}
	
	private void addAll(Set<String> rules, String[] strRules){
		for(String str : strRules){
			String rule = str.trim();
			if(rule.length()>0){
				rules.add(rule);
			}
		}
	}
}
